package com.plugin;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.config.PropertyRegistry;

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * 描述：生成请求vo和响应vo
 * 作者：刘飞华
 * 日期：2024/7/23 14:02
 */
public class VoGenerator extends PluginAdapter {

    private final Properties properties;

    private String author;

    private String createTime;

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    public VoGenerator() {
        this.properties = new Properties();
    }

    public VoGenerator(Properties properties) {
        this.properties = properties;
    }


    @Override
    public void setProperties(Properties properties) {
        this.properties.putAll(properties);
        this.author = properties.getProperty("author");
        SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        this.createTime = dateFormatter.format(new Date());
    }

    /**
     * 可以生成自定义的文件
     */
    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        List<GeneratedJavaFile> javaFiles = new ArrayList<>();
        javaFiles.add(genReqVoJavaFile("Add", introspectedTable, ""));
        javaFiles.add(genReqVoJavaFile("Delete", introspectedTable, ""));
        javaFiles.add(genReqVoJavaFile("Update", introspectedTable, ""));
        javaFiles.add(genReqVoJavaFile("Update", introspectedTable, "Status"));
        javaFiles.add(genReqVoJavaFile("Query", introspectedTable, "Detail"));
        javaFiles.add(genReqVoJavaFile("Query", introspectedTable, "List"));

        javaFiles.add(genRespVoJavaFile(introspectedTable, "Detail"));
        javaFiles.add(genRespVoJavaFile(introspectedTable, "List"));
        return javaFiles;
    }

    /**
     * 生成一个自定义文件
     */
    private GeneratedJavaFile genReqVoJavaFile(String type, IntrospectedTable introspectedTable, String suffix) {
        String targetPackage = properties.getProperty("targetPackage");
        String[] split = introspectedTable.getBaseRecordType().split("\\.");
        String typeName = targetPackage + ".req." + type + split[split.length - 1] + suffix + "ReqVo";
        //类的完全限定名（决定生成的文件的目录接口）
        TopLevelClass c = new TopLevelClass(typeName);

        //设置注释
        c.addJavaDocLine("/**");
        String remarks = introspectedTable.getRemarks().replace("表", "");
        c.addJavaDocLine(" * 描述: " + remarks);
        c.addJavaDocLine(" * 作者: " + author);
        c.addJavaDocLine(" * 日期: " + createTime);
        c.addJavaDocLine(" */");

        c.addJavaDocLine("@Data");
        c.addJavaDocLine("@Builder");
        c.addJavaDocLine("@NoArgsConstructor");
        c.addJavaDocLine("@AllArgsConstructor");
        c.addJavaDocLine("@Schema(description = \"" + remarks + type + suffix + "请求vo\")");

        c.setVisibility(JavaVisibility.PUBLIC);

        c.addSuperInterface(new FullyQualifiedJavaType("Serializable"));
        //导入的依赖包
        c.addImportedType(new FullyQualifiedJavaType("java.io.Serializable"));
        c.addImportedType(new FullyQualifiedJavaType("lombok.*"));
        c.addImportedType(new FullyQualifiedJavaType("io.swagger.v3.oas.annotations.media.*"));
        c.addImportedType(new FullyQualifiedJavaType("jakarta.validation.constraints.*"));
        //构建一个编译单元
        GeneratedJavaFile generatedJavaFile = new GeneratedJavaFile(
                c,
                context.getJavaModelGeneratorConfiguration().getTargetProject(),
                context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                context.getJavaFormatter());

        //分页设置
        if ("List".equals(suffix)) {
            Field pageNum = new Field("pageNum",new FullyQualifiedJavaType("java.lang.Integer"));
            pageNum.setVisibility(JavaVisibility.PRIVATE);
//            pageNum.setName("pageNum");
//            pageNum.setType(new FullyQualifiedJavaType("java.lang.Integer"));
            pageNum.setInitializationString("1");
            pageNum.addJavaDocLine("@Schema(description = \"pageNum第几页\", defaultValue = \"1\")");
            c.addField(pageNum);

            Field pageSize = new Field("pageSize",new FullyQualifiedJavaType("java.lang.Integer"));
            pageSize.setVisibility(JavaVisibility.PRIVATE);
//            pageSize.setName("pageSize");
//            pageSize.setType(new FullyQualifiedJavaType("java.lang.Integer"));
            pageSize.setInitializationString("10");
            pageSize.addJavaDocLine("@Schema(description = \"pageSize每页数量\", defaultValue = \"10\")");
            c.addField(pageSize);
        }

        for (IntrospectedColumn column : introspectedTable.getAllColumns()) {
            Field f = new Field(column.getJavaProperty(),column.getFullyQualifiedJavaType());
            f.setVisibility(JavaVisibility.PRIVATE);
//            f.setName(olumn.getJavaProperty()c);
//            f.setType(column.getFullyQualifiedJavaType());
            f.addJavaDocLine("@Schema(description = \"" + column.getRemarks() + "\", requiredMode = Schema.RequiredMode.REQUIRED)");
            if (column.getJavaProperty().contains("update") || column.getJavaProperty().contains("create")) {
                continue;
            }
            if ("java.util.Date".equals(column.getFullyQualifiedJavaType().getFullyQualifiedName())) {
                f.setType(new FullyQualifiedJavaType("java.lang.String"));
            }
            if ("java.lang.Byte".equals(column.getFullyQualifiedJavaType().getFullyQualifiedName())) {
                f.setType(new FullyQualifiedJavaType("java.lang.Integer"));
            }
            if (!"java.lang.String".equals(f.getType().getFullyQualifiedName())) {
                f.addJavaDocLine("@NotNull(message = \"" + column.getJavaProperty() + column.getRemarks() + "不能为空\")");
            } else {
                f.addJavaDocLine("@NotBlank(message = \"" + column.getJavaProperty() + column.getRemarks() + "不能为空\")");
            }
            c.addField(f);
        }



        return generatedJavaFile;
    }

    private GeneratedJavaFile genRespVoJavaFile(IntrospectedTable introspectedTable, String suffix) {
        String targetPackage = properties.getProperty("targetPackage");
        String[] split = introspectedTable.getBaseRecordType().split("\\.");
        String typeName = targetPackage + ".resp.Query" + split[split.length - 1] + suffix + "RespVo";
        //类的完全限定名（决定生成的文件的目录接口）
        TopLevelClass c = new TopLevelClass(typeName);

        //设置注释
        c.addJavaDocLine("/**");
        String remarks = introspectedTable.getRemarks().replace("表", "");
        c.addJavaDocLine(" * 描述: " + remarks);
        c.addJavaDocLine(" * 作者: " + author);
        c.addJavaDocLine(" * 日期: " + createTime);
        c.addJavaDocLine(" */");

        c.addJavaDocLine("@Data");
        c.addJavaDocLine("@Builder");
        c.addJavaDocLine("@NoArgsConstructor");
        c.addJavaDocLine("@AllArgsConstructor");
        c.addJavaDocLine("@Schema(description = \"" + remarks + suffix + "响应vo\")");

        c.setVisibility(JavaVisibility.PUBLIC);

        c.addSuperInterface(new FullyQualifiedJavaType("Serializable"));
        //导入的依赖包
        c.addImportedType(new FullyQualifiedJavaType("java.io.Serializable"));
        c.addImportedType(new FullyQualifiedJavaType("java.util.Date"));
        c.addImportedType(new FullyQualifiedJavaType("lombok.*"));
        c.addImportedType(new FullyQualifiedJavaType("io.swagger.v3.oas.annotations.media.*"));
        //构建一个编译单元
        GeneratedJavaFile generatedJavaFile = new GeneratedJavaFile(
                c,
                context.getJavaModelGeneratorConfiguration().getTargetProject(),
                context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                context.getJavaFormatter());

        for (IntrospectedColumn column : introspectedTable.getAllColumns()) {
            Field f = new Field(column.getJavaProperty(),column.getFullyQualifiedJavaType());
            f.setVisibility(JavaVisibility.PRIVATE);
//            f.setName(column.getJavaProperty());
//            f.setType(column.getFullyQualifiedJavaType());
            f.addJavaDocLine("@Schema(description = \"" + column.getRemarks() + "\")");
            if ("java.util.Date".equals(column.getFullyQualifiedJavaType().getFullyQualifiedName())) {
                f.addAnnotation("@JsonFormat(pattern = \"yyyy-MM-dd HH:mm:ss\", timezone = \"GMT+8\")");
                c.addImportedType("com.fasterxml.jackson.annotation.JsonFormat");
            }
            System.out.println("f = " + column.getFullyQualifiedJavaType().getFullyQualifiedName());
            if ("java.lang.Byte".equals(column.getFullyQualifiedJavaType().getFullyQualifiedName())) {
                f.setType(new FullyQualifiedJavaType("java.lang.Integer"));
            }
            c.addField(f);
        }

        return generatedJavaFile;
    }

}
